#include<iostream>

//用日期类学习操作符重载
  namespace Dateuse
  {
      int monthdayarr[]= {0,31,28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  }
class Date
{
public:
//构造函数
    //更好的日期构造函数,构造函数不只是去完成初始化,也可以检测是否合法
   	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;

		// 检查日期是否合法
		if (!(year >= 1
			&& (month >= 1 && month <= 12)
			&& (day >= 1 && day <= Getmonthday(year, month))))
		{
			std::cout << "非法日期" << std::endl;
		}
	}
    void Printdate()
    {
      std::cout<<"year:"<<_year<<" month:"<<_month<<"day:"<<_day<<std::endl;
    }
      //返回类型 操作符 (参数1,参数2)这里省略了一个参数,因为有this 指针
    bool operator==(const Date &d)
    {
        return _year==d._year&&_month==d._month&&_day==d._day;
    }
    bool operator>(const Date &d)
    {
        if(_year>d._year)
        {
            return true;
        }
        if(_year==d._year&&_month>d._month)
        {
            return true;
        }
        if(_month==d._month&&_day>d._day&&_year==d._year)
        {
            return true;
        }
        return false;
    }

    int Getmonthday(int year,int month) 
    {
       if(month==2&&((year%4==0&&year%100!=0)||(year%400==0)))
       {
        return 29;
       }
       else{
        return Dateuse::monthdayarr[month];
       }
    }
    //传引用返回 别名,被修改了
    Date& operator+=(int day)
	{
		_day += day;
		while (_day > Getmonthday(_year, _month))
		{
			_day -= Getmonthday(_year, _month);
			_month++;

			if (_month == 13)
			{
				++_year;
				_month = 1;
			}
		}

		return *this;
	}
    //传值返回
    Date operator+(int day)
	{
        //拷贝构造
		Date ret(*this);
		ret += day;
		return ret;
	}
    //赋值重载"=" 与拷贝构造一样都用来拷贝，拷贝构造，用来初始化
    //而赋值重载用来赋值已经存在的对象 
    //默认成员函数
    //有些默认可以满足，但是有些深拷贝需要自己写
    Date& operator =(const Date &d)
    {
        _year=d._year;
        _day=d._day;
        _month=d._month;
        return *this;
    }
private:
    //用下划线来区分私有用传值
   int _year;
	int _month;
	int _day;
};
 void test1()
 {
    Date d1(2023,4,24);
    Date d2;
    Date d3=d1;//拷贝构造与拷贝复制区别有没有两个存在的变量
    d2=d1;//d2.operator=d1  默认第一参数为左操作数，右边为右操作数
    d1.Printdate();
    d3.Printdate();
 }
int main()
{
   test1();
   return 0;
}